/*
******************************************************************************************
**
**  Copyright (C) 2011, Fujian WITSI Micro-electronic Tech. CO.,LTD., All Rights Reserved.
**
******************************************************************************************
*/
/*
******************************************************************************************
**
**	File: printer.c
**
**	Brief:
**
**	Logs:
**		2012.12.26		Created by ttlc
**
******************************************************************************************
*/
#include <stdint.h>
#include "config.h"
#include "apitrans.h"
#include "result.h"
#include "devapi.h"
#include "arq_cmd.h"

/*
******************************************************************************************
**	local referenced extern function and variables 
******************************************************************************************
*/

/*
******************************************************************************************
**	local referenced macro defines & type defines
******************************************************************************************
*/

/*
******************************************************************************************
**	local function prototype
******************************************************************************************
*/

/*
******************************************************************************************
**	global variables 
******************************************************************************************
*/

/*
******************************************************************************************
**	Implementation functions 
******************************************************************************************
*/

int api_buzzer_ctl(unsigned char *cmd, int len)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t times;
	int buzzer_time=0;
	int min_time = 0;
	uint8_t offset = 0;
	int i = 0;
	
	times = cmd[offset];
	offset += 1;
	buzzer_time = BCDtoDec(cmd+offset,4);
	offset += 4;
	min_time = BCDtoDec(cmd+offset,4);
	offset += 4;
	if(offset != len){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}
	for(i=0; i<times; i++){
		buzzer_start();
		mdelay(buzzer_time);
		buzzer_stop();
		mdelay(min_time);
	}
	offset = 0;
	memcpy(cmd,&ret,2);
	offset += 2;
	return offset;
}


int api_led_ctl(unsigned char *cmd, int len)
{
	uint8_t nr;
	uint8_t onoff;
	uint16_t ret = DEAL_SUCCESS;;
	uint8_t offset = 0;
	nr = cmd[offset++];
	onoff = cmd[offset++];
	if(offset != len){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}
	led_ctrl(nr,  onoff);
	memcpy(cmd,&ret,2);
	offset = 2;
	return offset;
}
static int str2tm(const char * str, struct tm * tp)
{
        int i, k = 0;
        char dt[20];

        for (i = 0; i < 14; i++) {
                dt[k ++] = *(str + i);
                if (k >= 4 && (k % 3 == 1)) {
                        dt [k ++] = 0;
                }
        }

        tp->tm_year = strtoul(dt, (char **)0, 10) - 1900;
        tp->tm_mon = strtoul(dt + 5, (char **)0, 10) - 1;
        tp->tm_mday = strtoul(dt + 8, (char **)0, 10);
        tp->tm_hour = strtoul(dt + 11, (char **)0, 10);
        tp->tm_min = strtoul(dt + 14, (char **)0, 10);
        tp->tm_sec = strtoul(dt + 17, (char **)0, 10);
        return 0;
}

struct time_val {
        time_t      tv_sec;
        suseconds_t tv_usec;
};

int api_set_time(unsigned char *cmd, int len)
{
	uint8_t tstr[15]={0};
	time_t tv;
    struct tm t;
	uint16_t ret;
	uint8_t offset = 0;
	if(len != 14){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}
	memcpy(tstr,cmd,14);
	str2tm((char*)tstr, &t);
    tv = mktime(&t);
	struct time_val val;
    val.tv_sec = tv;
    val.tv_usec = 0;
    settimeofday(&val, NULL);
	ret = DEAL_SUCCESS;
	memcpy(cmd,&ret,2);
	offset = 2;
	return offset;
}


int api_get_time(unsigned char *cmd, int len)
{

    char tstr[15]={0};
	uint16_t ret = DEAL_SUCCESS;
	uint16_t offset = 0;
	if(len != 0){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}

	get_time(tstr);
	memcpy(cmd+offset,&ret,2);
	offset += 2;
	memcpy(cmd+offset,tstr,14);
	offset += 14;
	return offset;
}

int api_time_delay(unsigned char *cmd, int len)
{
	uint32_t ms;
	uint16_t ret = DEAL_SUCCESS;
	ms = BCDtoDec(cmd,4);
	mdelay(ms);
	memcpy(cmd,&ret,2);
	
	return 2;
}

int api_get_strrng( char *cmd, int inlen)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t len = 0;
	char buf[256]= {0};
	uint16_t offset = 0;
	len = cmd[offset++];
	if(offset != inlen){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}
	rng_get_string((uint8_t*)buf,len);
	offset = 0;
	memcpy(cmd+offset,&ret,2);
	offset += 2;
	memcpy(cmd+offset,buf,len);
	offset += len;
	return offset;
}

int api_nv_read(unsigned char *cmd, int inlen)
{
	uint16_t ret = DEAL_SUCCESS;
	int len;
	int offset = 0;;
	int offset1 = 0;
	uint8_t buf[MAX_SIZE]={0};
	offset = BCDtoDec(cmd,4);
	offset1 += 4;
	len = BCDtoDec(cmd+offset1,2);
	if(len > MAX_SIZE){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}
	offset1 += 2;
	if(offset1 != inlen || (len > MAX_SIZE)){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}
	
	len = nv_read(offset,buf,len);
	if(len <= 0){
		ret = ERROR_NV_READ;
		memcpy(cmd,&ret,2);
		return -1;
	}
	offset1 = 0;
	memcpy(cmd,&ret,2);
	offset1 += 2;
	DectoBCD(len,cmd+offset1,2);
	offset1 += 2;
	memcpy(cmd+offset1,buf,len);
	offset1 += len;
	return offset1;
}

int api_nv_write(unsigned char *cmd, int inlen)
{
	uint16_t ret = DEAL_SUCCESS;
	int len;
	int offset = 0;
	int offset1 = 0;
	uint8_t buf[MAX_SIZE]={0};
	offset = BCDtoDec(cmd,4);
	offset1 += 4;
	len = BCDtoDec(cmd+offset1,2);
	offset1 +=2;
	if(len > MAX_SIZE){
		ret = ERROR_PARAM;
		memcpy(cmd, &ret, 2);
		return -1;
	}
	memcpy(buf,cmd+offset1,len);
	offset1 += len;
	if(offset1 != inlen || (len > MAX_SIZE)){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}
	len = nv_write(offset,buf, len);
	if(len <= 0){
		ret = ERROR_NV_WRITE;
		memcpy(cmd,&ret,2);
		return -1;
	}	
	offset1 = 0;
	memcpy(cmd,&ret,2);
	offset1 +=2;
	DectoBCD(len,cmd+offset1,2);
	offset1 +=2;
	return offset1;
}


int api_get_sysparm(unsigned char *cmd, int inlen)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t mod;
	uint8_t buf[256]={0};
	uint8_t len = 0;
	uint8_t offset = 0;
    
	mod = cmd[offset++];
	if(offset != inlen){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}
	switch(mod){
		case 0x01:
			len = sys_get_param(SYS_PARAM_SYSTEM_VER,buf,32);
			break;
		case 0x02:
			len = sys_get_param(SYS_PARAM_DEVICE_SN,buf,32);
			break;
		case 0x03:
			len = sys_get_param(SYS_PARAM_HW_VER,buf,4);
			break;
		case 0x04:
			len = sys_get_param(SYS_PARAM_LCD_GRAY,buf,4);
			break;
		case 0x05:
			len = sys_get_param(SYS_PARAM_APPFS_FREE_SPACE,buf,4);
			break;
        case 0x06:
			len = sys_get_param(SYS_PARAM_PSAM_NO,buf,32);
			break;
		default:
			ret = ERR_RARM_TPYE;
			break;
	}
	offset = 0;
	memcpy(cmd,&ret,2);
	offset += 2;
	cmd[offset++] = len;
	if(len){
		memcpy(cmd+offset,buf,len);
		offset += len;
	}
	return offset;
}

int api_set_sysparm(unsigned char *cmd, int len)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t offset = 0;
	uint8_t mod= cmd[offset++];
    int tmp;
	int value = cmd[offset++];
	if(offset != len){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}
	switch(mod){
		case 0x01:

			tmp = sys_set_param(SYS_PARAM_KEY_BEEP, (void*)value, 4);

            break;
		case 0x02:
			sys_set_param(SYS_PARAM_LCD_GRAY, (void*)value, 4);
			break;
		default:
			ret = ERR_RARM_TPYE;
			break;
	}
	memcpy(cmd,&ret,2);
	offset = 2;
	return offset;
}

int api_sys_cmd_mod(unsigned char *cmd, int len)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t offset = 0;


	if(offset != len){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}

	return DEAL_GO_CMD;
}


static int get_month(uint8_t *mmdd)
{	
	int i = 0;
	uint8_t time[10] = __DATE__;
	const unsigned char MonthStr[12][4] = {"Jan", "Feb", "Mar", "Apr", "May", \
			"Jun", "Jul", "Aug", "Sep", "Oct", "Nov","Dec"};
	for(i = 0; i< 12; i++){
		if(memcmp(MonthStr[i], time, 3) == 0){
			break;
		}
	}
	sprintf(mmdd, "%02d", i+1);
	memcpy(mmdd+2, time+4, 2);

	return 0;
}

int api_getrdp_ver(unsigned char *cmd, int len)
{
	uint16_t ret = DEAL_SUCCESS;
	uint8_t offset = 0;
	
	uint8_t mmdd[5] = {0};
	uint8_t rdp_ver[64] = {0};


	if(offset != len){
		ret = ERROR_PARAM;
		memcpy(cmd,&ret,2);
		return -1;
	}

	memcpy(rdp_ver, app_version(),  strlen(app_version()));
	

	memcpy(cmd,&ret,2);
	offset = 2;
	cmd[offset++] = strlen(app_version());
	memcpy(cmd+offset, rdp_ver, strlen(app_version()));
	offset += strlen(rdp_ver);
	
	return offset;
}



static func_t misc_fun[] = {
	NULL, api_buzzer_ctl,api_led_ctl,api_set_time,api_get_time, \
		  api_get_strrng,api_nv_read,api_nv_write,api_get_sysparm,\
		  api_set_sysparm, api_sys_cmd_mod, api_getrdp_ver
	};

int cmd_misc(uint8_t cmd,uint8_t *buf,int len)
{
	if(cmd < 0x01 || cmd > FUN_SIZE(misc_fun))
		return -5;
	return misc_fun[(int)cmd]((uint8_t*)buf,len);
}


